package com.citybox.shared.utils.jwt;

import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.security.Security;

@Slf4j
@Component
public class WechatDecryptUtil {

    static {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
    }

    public String decrypt(String encryptedData, String sessionKey, String iv) {
        try {
            log.info("Starting WeChat data decryption");

            byte[] dataByte = Base64.decodeBase64(encryptedData);
            byte[] keyByte = Base64.decodeBase64(sessionKey);
            byte[] ivByte = Base64.decodeBase64(iv);

            if (keyByte.length != 24) {
                log.error("Invalid session key length: {}", keyByte.length);
                throw new RuntimeException("会话密钥长度无效");
            }

            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
            params.init(new IvParameterSpec(ivByte));

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");

            cipher.init(Cipher.DECRYPT_MODE, keySpec, params);

            byte[] resultByte = cipher.doFinal(dataByte);
            if (null == resultByte || resultByte.length == 0) {
                log.error("Decryption result is empty");
                throw new RuntimeException("解密结果为空");
            }

            String result = new String(resultByte, StandardCharsets.UTF_8);
            log.info("WeChat data decryption successful");

            return result;

        } catch (Exception e) {
            log.error("WeChat data decryption failed", e);
            throw new RuntimeException("微信数据解密失败: " + e.getMessage());
        }
    }

    public boolean checkSignature(String rawData, String sessionKey, String signature) {
        try {
            log.info("Checking data signature");

            String data = rawData + sessionKey;

            java.security.MessageDigest crypt = java.security.MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(data.getBytes(StandardCharsets.UTF_8));

            String calculatedSignature = byteToHex(crypt.digest());

            boolean isValid = calculatedSignature.equals(signature);
            log.info("Signature check result: {}", isValid);

            return isValid;

        } catch (Exception e) {
            log.error("Signature check failed", e);
            return false;
        }
    }

    private String byteToHex(final byte[] hash) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            if ((b & 0xff) < 0x10) {
                hexString.append("0");
            }
            hexString.append(Integer.toHexString(b & 0xff));
        }
        return hexString.toString();
    }
}
